/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package jsf.generator.pages;

import net.db.generator.utils.ClassGeneratorUtil;
import net.db.generator.field.models.BaseFieldModel;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileWriter;
import java.util.List;
import java.util.Properties;

/**
 *
 * @author abosancic
 */
public class JSFBaseWriter {

    protected StringBuilder stringXHTML = null;
    protected String packageName;
    protected String importPackages[];
    protected String className;
    protected String fileName = "Create";

    protected BaseFieldModel[] fields;
    
    protected String spaces = "    ";
    protected String template = "template";
    
    protected Properties properties;

    public JSFBaseWriter() {
      stringXHTML = new StringBuilder();
      properties = new Properties();
    }

    public void generateXHTML() {
        
        addInitProperties();
        
        generateDoctypeDeclarations();
        generateImports();
        generateStartTemplate();
        
        generateDefineTitle();
        generateDefineBody();
        generateMessagePanel();
        
        generateStartForm();
        generateFields();
        
        generateEndForm();
        generateEndBody();
        generateEndTemplate();
        generateFooter();
        // write this class
        writeFile();
    } 
    
    protected void generateDoctypeDeclarations(){
       stringXHTML.append("<?xml version=\"1.0\" encoding=\"UTF-8\" ?>").append("\n")
                  .append("<!DOCTYPE html PUBLIC \"-//W3C//DTD XHTML 1.0 Transitional//EN\" \"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd\">")
                  .append("\n");
    }
    
    protected void generateStartTemplate(){
        stringXHTML.append(spaces).append("<ui:composition template=\"/" + template + ".xhtml\">").append("\n");
    }
    
    protected void generateEndTemplate(){
        stringXHTML.append(spaces).append("</ui:composition>").append("\n");
    }
    
    protected void generateDefineTitle(){
        stringXHTML.append(spaces).append("<ui:define name=\"title\">\n")
                .append(spaces).append(spaces).append("<h:outputText value=\"#{bundle.Create" + ClassGeneratorUtil.humanize(className) + "Title}\"></h:outputText>\n")
                .append(spaces).append("</ui:define>").append("\n");
        // add bundle
        properties.put("Create" + ClassGeneratorUtil.humanize(className) + "Title", "Create New " + ClassGeneratorUtil.humanize(className));
    }
    
    protected void generateDefineBody(){
        stringXHTML.append(spaces).append("<ui:define name=\"body\">\n");
    }

    protected void generateImports(){
        stringXHTML.append("<html xmlns=\"http://www.w3.org/1999/xhtml\"\n"
                + "      xmlns:ui=\"http://java.sun.com/jsf/facelets\"\n"
                + "      xmlns:h=\"http://java.sun.com/jsf/html\"\n"
                + "      xmlns:f=\"http://java.sun.com/jsf/core\">").append("\n\n");
    }
    
    protected void generateMessagePanel(){
        stringXHTML.append(spaces).append("<h:panelGroup id=\"messagePanel\" layout=\"block\">\n")
            .append(spaces).append(spaces).append("<h:messages errorStyle=\"color: red\" infoStyle=\"color: green\" layout=\"table\"/>\n")
            .append(spaces).append("</h:panelGroup>").append("\n");
    }
    
    protected void generateFooter(){
         stringXHTML.append("</html>\n");
    }
    
    protected final synchronized void writeFile() {

        try {
            String path = "." + File.separator + "src" + File.separator;
            if (getPackageName() != null) {
                path += getPackageName().replace(".", File.separator);
                new File(path).mkdirs();
            }

            FileWriter fstream = new FileWriter(path + File.separator + ClassGeneratorUtil.humanize(getFileName()) + ".xhtml");
            BufferedWriter out = new BufferedWriter(fstream);
            out.write(stringXHTML.toString());
            //Close the output stream
            out.close();
        } catch (Exception e) {//Catch exception if any
            System.err.println("Error: " + e.getMessage());
        }
        
        stringXHTML = new StringBuilder();
    }

    protected void generateFields() {
        
        StringBuilder toStringMethod = new StringBuilder();
        
        for (BaseFieldModel fieldModel : fields) {
            String field = fieldModel.getFieldName();
            field = ClassGeneratorUtil.humanizeToField(fieldModel.getFieldName());
            stringXHTML.append(spaces).append(spaces).append("<h:outputLabel value=\"#{bundle.Create" + ClassGeneratorUtil.humanize(className) + "Label_" + field + "}\" for=\"" + field + "\" />\n")
                    .append(spaces).append(spaces).append("<h:inputText id=\"" + field + "\" value=\"#{" + ClassGeneratorUtil.humanizeToField(className) + "Controller.selected." + field + "}\" "
                    + "title=\"#{bundle.Create" + ClassGeneratorUtil.humanize(className) + "Title_" + field + "}\" "
                    + "required=\"true\" "
                    + "requiredMessage=\"#{bundle.Create" + ClassGeneratorUtil.humanize(className) + "RequiredMessage_" + field + "}\"/>");
            stringXHTML.append("\n");
            stringXHTML.append("<br />");
            stringXHTML.append("\n");
            
            // add bundle
            properties.put("Create" + ClassGeneratorUtil.humanize(className) + "Label_" + field, ClassGeneratorUtil.humanize(field) + ":");
            properties.put("Create" + ClassGeneratorUtil.humanize(className) + "Title_" + field, ClassGeneratorUtil.humanize(field));
            properties.put("Create" + ClassGeneratorUtil.humanize(className) + "RequiredMessage_" + field, "The " + ClassGeneratorUtil.humanizeToField(field) + " field is required.");

        }
        
        stringXHTML.append(spaces).append("\n");
    }

    protected void generateStartForm() {
        stringXHTML.append(spaces).append("<h:form class=\"jumbotron\">\n")
                   //.append(spaces).append("<h:panelGrid columns=\"2\">\n");
                .append(spaces).append("<h:panelGroup id=\"dataPanel\" layout=\"block\">\n");
                
    }

    protected void generateEndForm() {
        stringXHTML.append(spaces).append(" </h:panelGroup>\n")
                .append(spaces).append("<br />\n")
                .append(spaces).append("<h:commandLink action=\"#{" + ClassGeneratorUtil.humanizeToField(className) + "Controller.create}\" value=\"#{bundle.Create" + ClassGeneratorUtil.humanize(className) + "SaveLink}\" />\n")
                .append(spaces).append(spaces).append("<br />\n")
                .append(spaces).append(spaces).append("<br />\n")
                .append(spaces).append("<h:commandLink action=\"#{" + ClassGeneratorUtil.humanizeToField(className) + "Controller.prepareList}\" value=\"#{bundle.Create" + ClassGeneratorUtil.humanize(className) + "ShowAllLink}\" immediate=\"true\"/>\n")
                .append(spaces).append("<br />\n")
                .append(spaces).append("<br />\n")
                .append(spaces).append("<h:link outcome=\"/index\" value=\"#{bundle.Create" + ClassGeneratorUtil.humanize(className) + "IndexLink}\"/>\n")
                .append(spaces).append("</h:form>\n");
        
        // add bundle
        properties.put("Create" + ClassGeneratorUtil.humanize(className) + "SaveLink", "Save");
        properties.put("Create" + ClassGeneratorUtil.humanize(className) + "ShowAllLink", "Show All " + ClassGeneratorUtil.humanize(className) + " Items");
        properties.put("Create" + ClassGeneratorUtil.humanize(className) + "IndexLink", "Index");
    }

    protected void generateEndBody() {
         stringXHTML.append(spaces).append("</ui:define>").append("\n");
    }
    
     // setters and getters
    public String getClassName() {
        return className;
    }

    public void setClassName(String className) {
        this.className = className;
    }

    public BaseFieldModel[] getFields() {
        return fields;
    }

    public void setFields(BaseFieldModel[] fields) {
        this.fields = fields;
    }

    public void setFields(List<BaseFieldModel> fields) {
        this.fields = fields.toArray(new BaseFieldModel[fields.size()]);
    }

    public String getPackageName() {
        return packageName;
    }

    public void setPackageName(String packageName) {
        this.packageName = packageName;
    }

    public String[] getImportPackages() {
        return importPackages;
    }

    public void setImportPackages(String[] importPackages) {
        this.importPackages = importPackages;
    }
 
    public String getFileName() {
        return fileName;
    }

    public void setFileName(String fileName) {
        this.fileName = fileName;
    }
    
    public Properties getProperties() {
        return properties;
    }

    public void setProperties(Properties properties) {
        this.properties = properties;
    }

    protected void addInitProperties() {
        String name = ClassGeneratorUtil.humanize(className);
        properties.put(name + "Created", name + " was successfully created.");
        properties.put(name + "Updated", name + " was successfully updated.");
        properties.put(name + "Deleted", name + " was successfully deleted.");
    }

}
